package com.ecarx.vhaltests.hy11.testcases.drivemode;



import static vendor.ecarx.xma.automotive.vehicle.V2_0.ECarXVehicleProperty.DRIVEMODE_SCENE_REST_SWITCH;

import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.hardware.automotive.vehicle.V2_0.VehicleAreaSeat;
import android.util.Log;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;


//SW_FC_041_033 情景模式-休息模式
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class DriveModeSceneRestSwitchTest extends VhalUnitTestBase {

    private static final String TAG = "DRIVEMODE_SCENE_REST_SWITCH";


    private static IpcpClient ipcpClient = new IpcpClient();

    private static final int ROW1_LEFT = VehicleAreaSeat.ROW_1_LEFT;
    private static final int ROW2_RIGHT = VehicleAreaSeat.ROW_1_RIGHT;


    private static boolean halValue;
    private static int halStatus;
    final static Object lock = new Object();

    @BeforeClass
    public static void testInit() {
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, DRIVEMODE_SCENE_REST_SWITCH, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig();
    }

    @Test
    public void testDriveModeSceneRestSwitchAvailable() {
        setDriveModeSceneRestSwitchAvailable();
        lockWait();
        Assert.assertEquals(halStatus, 0);
        testDriveModeSceneRestSwitchAvai(ROW1_LEFT);
        testDriveModeSceneRestSwitchAvai(ROW2_RIGHT);
    }

    @Test
    public void testDriveModeSceneRestSwitchNotAvailable() {
        setDriveModeSceneRestSwitchNotAvailable();
        lockWait();
        Assert.assertEquals(halStatus, 1);
        testDriveModeSceneRestSwitchNotAvai(ROW1_LEFT);
        testDriveModeSceneRestSwitchNotAvai(ROW2_RIGHT);
    }

    @Test
    public void testDriveModeSceneRestSwitchDrvrOff() {
        setDriveModeSceneRestSwitchAvailable();
        delay();
        setDriveModeSceneRestSwitchValue(false, ROW1_LEFT);
        lockWait();
        Assert.assertEquals(halValue, false);
        testDriveModeSceneRestSwitchValue(false, ROW1_LEFT);
    }

    @Test
    public void testDriveModeSceneRestSwitchDrvrOn() {
        setDriveModeSceneRestSwitchAvailable();
        delay();
        setDriveModeSceneRestSwitchValue(true, ROW1_LEFT);
        lockWait();
        Assert.assertEquals(halValue, true);
        testDriveModeSceneRestSwitchValue(true, ROW1_LEFT);
    }

    @Test
    public void testDriveModeSceneRestSwitchPassOff() {
        setDriveModeSceneRestSwitchAvailable();
        delay();
        setDriveModeSceneRestSwitchValue(false, ROW2_RIGHT);
        lockWait();
        Assert.assertEquals(halValue, false);
        testDriveModeSceneRestSwitchValue(false, ROW2_RIGHT);
    }

    @Test
    public void testDriveModeSceneRestSwitchPassOn() {
        setDriveModeSceneRestSwitchAvailable();
        delay();
        setDriveModeSceneRestSwitchValue(true, ROW2_RIGHT);
        lockWait();
        Assert.assertEquals(halValue, true);
        testDriveModeSceneRestSwitchValue(true, ROW2_RIGHT);
    }


    private void testDriveModeSceneRestSwitchValue(boolean value, int area){
        boolean halValue = mCarPropertyMgr.getBooleanProperty(DRIVEMODE_SCENE_REST_SWITCH, area);
        Assert.assertEquals(halValue, value);
    }

    private void setDriveModeSceneRestSwitchValue(boolean value, int area){
        mCarPropertyMgr.setBooleanProperty(DRIVEMODE_SCENE_REST_SWITCH, area, value);
    }

    private void setDriveModeSceneRestSwitchAvailable(){
        setGearLvrIndcn(0);
        setCarmodUsgMod(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_CONVENIENCE);
    }

    private void setDriveModeSceneRestSwitchNotAvailable(){
        setGearLvrIndcn(2);
        setCarmodUsgMod(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_CONVENIENCE);
    }

    private static void setConfig() {
        int ccSvcId = 135;
        int[] ccOperIds = {200};

        int cemSvcId = 37;
        int[] cemOperIds = {999};

        int vddmSvcId = 48;
        int[] vddmOperIds = {999};

        ipcpClient.setConfig(ccSvcId, ccOperIds);
        ipcpClient.setConfig(cemSvcId, cemOperIds);
        ipcpClient.setConfig(vddmSvcId, vddmOperIds);

        int[] configs = {616};
        int[] values = {5};
        boolean ccRet = ipcpClient.setCarconfigSignal(ccSvcId, ccOperIds[0], configs, values);
        Assert.assertTrue(ccRet);

    }

    private void setCarmodUsgMod(int carMod, int usgMod)
    {
        int cemSvcId = 37;
        int[] cemOperIds = {999};

        String[] cems = {"vehModMngtGlbSafe1CarModSts1", "vehModMngtGlbSafe1UsgModSts"};
        int[] cemValues = {carMod, usgMod};
        boolean cemRet = ipcpClient.setCEMSignal(cemSvcId, cemOperIds[0], cems, cemValues);
        Assert.assertTrue(cemRet);
    }

    private void setGearLvrIndcn(int value){
        int vddmSvcId = 48;
        int[] vddmOperIds = {999};

        String[] vddms = {"gearLvrIndcn"};
        int[] vddmValues = {value};
        boolean vddmsRet = ipcpClient.setVDDMSignal(vddmSvcId, vddmOperIds[0], vddms, vddmValues);
        Assert.assertTrue(vddmsRet);
    }

    private void testDriveModeSceneRestSwitchAvai(int area){
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(DRIVEMODE_SCENE_REST_SWITCH, area);
        Assert.assertTrue(isAvail);
    }

    private void testDriveModeSceneRestSwitchNotAvai(int area){
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(DRIVEMODE_SCENE_REST_SWITCH, area);
        Assert.assertFalse(isAvail);
    }

    private static final CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                Log.d(TAG, carPropertyValue.toString());
                halValue = (boolean)carPropertyValue.getValue();
                halStatus = carPropertyValue.getStatus();
                synchronized (lock) {
                    lock.notify();
                }
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {
        }
    };

    public void lockWait() {
        try {
            synchronized (lock) {
                lock.wait(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}